import cv2
import numpy as np
import math
import time
import imutils
from  imutils.video import VideoStream, videostream
import numpy
import pyzbar.pyzbar as pyzbar
import argparse
import datetime
from PIL import Image,ImageEnhance
import serial
import binascii


def port_open(): #串口打开函数

    if(ser.isOpen()==False):
        ser.open()

    if(ser.isOpen()):
        print("串口打开成功")
    else:
        print("串口打开失败")

def port_close(): #串口关闭函数

    if(ser.isOpen()):
        ser.close()

    if(ser.isOpen()==False):
        print("串口关闭成功")
    else:
        print("串口关闭失败")

def send(send_date):  #串口发送函数
    #send_date为发送数据
    if(ser.isOpen()==False):
        port_open()
    if(ser.isOpen()):
        ser.write(send_date.encode('utf-8'))

        print("发送成功",send_date)
    else:
        print("发送失败")

# def barcode_recog():
#     print("开始识别二维码")
#     vs=videostream(0).start()#调用摄像头
#     time.sleep(2.0)#休眠2s缓一缓
#     flag=False#后面break用
#     while True:
#         frame=vs.read()#frame为图片
#         frame=imutils.resize(frame,width=1000)#解析二维码信息
#         #找到视频中的条形码，并解析（imutils)所有条形码
#         barcodes=pyzbar.decode(frame)#保存解析后的二维码信息

#         for barcode in barcodes:
#             (x,y,w,h)=barcode.rect
#             cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
#             #条形码数据为字节对象，转化成字符串
#             barcodeDate=barcode.date.decode("utf-8")#二维码信息
#             barcodeType=barcodeDate.type

#             barcodeDate=list(barcodeDate)
#             #列表格式
#             #需要改为通信协议可用的信息
#             barcodeDate.pop(3)

#             barcodeDate=''.join((barcodeDate))
#             barcodeDate='a'+barcodeDate+'z'#通讯格式
#             print(barcodeDate)
#             send(barcodeDate)
#             #发送给串口
#             if barcodeDate !="":
#                 flag=True#改状态量，跳出循环
#         cv2.imshow("barcode",frame)
#         cv2.waitKey(5)
#         if flag:
#             print("二维码函数结束")
#             time.sleep(2)#两秒时间来展示图形化窗口结果
#         break#跳出
#     vs.stop()#视频流释放
#     cv2.destroyAllWindows()

def barcode_recog_new():
    #二维码识别优化版本
    print("[INFO] starting video stram...")
    vs=VideoStream(4).start()
    time.sleep(2.0)
    flag=False
    frame=vs.read()
    frame=imutils.resize(frame,width=1000)
    barcodes=pyzbar.decode(frame)
    for barcode in barcodes:
        (x,y,w,h)=barcode.rect
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0.255),2)

        barcodeDate=barcode.data.decode("utf-8")
        barcodeType=barcode.type
        barcodeDate=list(barcodeDate)
        #barcodeDate.pop(3)
        barcodeDate=''.join(barcodeDate)
        barcodeDate='a'+barcodeDate+'z'
        print(barcodeDate)
        send(barcodeDate)
        us=ser.read(10)
        print(us)
        if barcodeDate !="":
            flag=True
    cv2.imshow("Barcode Scanner",frame)
    cv2.waitKey(5)
    if flag:
        print("识别成功，解析成功")
    cv2.destroyAllWindows()
    vs.stop()
    return flag


def recogniseByColor(ball_color):
    #ball_color为要识别的颜色
    ret,frame=cap.read()
    frame=imutils.resize(frame,width=300)
    frame=frame[60:120,120:200]
    gs_frame=cv2.GaussianBlur(frame,(5,5),0)#高斯模糊
    hsv=cv2.cvtColor(gs_frame,cv2.COLOR_BGR2HSV)#转化为HSV
    erode_hsv=cv2.erode(hsv,None,iterations=2)#腐蚀，粗的变细
    inRange_hsv=cv2.inRange(erode_hsv,color_dist[ball_color]['Lower'],color_dist[ball_color]['Upper'])
    cnts=cv2.findContours(inRange_hsv.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
    cv2.imshow("color",frame)#颜色块展示
    cv2.waitKey(5)
    # if(len(cnts)==0):
    #     time.sleep(0.5)
    #     print("无该颜色")
    #     return False
    # else:

    #     if ball_color=='blue':
    #         color="333"
    #         print(color)
    #         send(color)

    #     if ball_color=='red':
    #         color="444"
    #         print(color)
    #         send(color)

    #     if ball_color=='green':
    #         color="222"
    #         print(color)
    #         send(color)
    #     #下面四句是显示效果，可以注释掉
    #     c=max(cnts,key=cv2.contourArea)
    #     rect=cv2.minAreaRect(c)
    #     box=cv2.boxPoints(rect)
    #     cv2.drawContours(frame,[np.int0(box)],-1,(0,255,255),2)

    cv2.imshow('color',frame)
    cv2.waitKey(1)
    return True
vs.stop()
cv2.destroyAllWindows()



#ser=serial.Serial("/dev/ttyUSB0",115200,timeout=3)
ser=serial.Serial("/dev/ttyUSB0",115200,timeout=3)
recogTime=20#识别时间
gapTime=3#机械臂旋转调整时间
a=1
us=1#下位机发送的，
#颜色识别范围
color_dist={'red':{'Lower':np.array([156,43,60]),'Upper':np.array([100,255,255])},
            'blue':{'Lower':np.array([100,43,46]),'Upper':np.array([124,255,255])},
            'green':{'Lower':np.array([35,43,35]),'Upper':np.array([77,255,255])},}


while True:
    port_open()
    time.sleep(2)
    print("等待发送")

    # us_new=ser.read(10)
    # long_of_us=len(us_new)
    # print("信号length:",long_of_us)
    # if(long_of_us):
    #     us=us_new[long_of_us-1]
    # else:
    #     us=us
    # print("这是第",a,"次while循环")
    # a=a+1
    #print("发送过来的是:",us)
    

    green_flag=1
    red_flag=1
    blue_flag=1

    if us==2 or us==3 or us==4:
        cap=cv2.VideoCapture(2)
        if not cap.isOpened():
            print("摄像头未打开")
            exit(0)

        cnt=0

        for i in "aap":
            ###绿色：2，蓝色：3，红色：1
            if us==2 and green_flag:
                ##################################
                ball_color='green'
                time0=time.time()#读取当前时间
                print("识别绿色")
                #循环
                while time.time()-time0<recogTime:
                    ret,frame=cap.read()
                    if ret:#读取到摄像头
                        if frame is not None:#摄像头有图像
                            if(recogniseByColor(ball_color)):#识别到了颜色
                                print("成功识别绿色")
                                cnt=cnt+1
                                green_flag=0
                                break
                        else:
                            print("无画面")
                    else:
                        print("无法读取摄像头！")
                send(cnt)       
                cap.release()#释放资源
               # us=us+1#识别下一个颜色
               # break#颜色识别成功之后，跳出该颜色while的循环-

            if us==3 and blue_flag:
                
                ##################################
                ball_color='blue'
                time2=time.time()
                time.sleep(gapTime)
                print("识别蓝色")
                while time.time()-time2<recogTime:
                    ret,frame=cap.read()
                    if ret:
                        if frame is not None:
                            if(recogniseByColor(ball_color)):
                                print("成功识别蓝色")
                                cnt=cnt+1
                                blue_flag=0
                                break
                        else:
                            print("无画面")
                    else:
                        print("无法读取摄像头！")
                send(cnt)
                cap.release()
                #us=us+1
                #break

            if us==1 and red_flag:
                
                ##################################
                ball_color='red'
                time1=time.time()
                time.sleep(gapTime)
                print("识别红色")
                while time.time()-time1<recogTime:
                    ret,frame=cap.read()
                    if ret:
                        if frame is not None:
                            if(recogniseByColor(ball_color)):
                                print("成功识别红色")
                                cnt=cnt+1
                                red_flag=0
                                break
                        else:
                            print("无画面")
                    else:
                        print("无法读取摄像头！")
                send(cnt)
                cap.release()
                #break

    if us==0x01:
        flag=barcode_recog_new()
        if flag:
            us=us+1 
        #send("a123321z")
        #time.sleep(1)
        #send("a123321z")


    if us==0x05:
        cv2.destroyAllWindows()

